home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / netz / term / extras / source / term-source.lha / HotkeyPanel.c < prev    next >
C/C++ Source or Header  |  1995-03-19  |  15KB  |  684 lines

  1. /*
  2. **    HotkeyPanel.c
  3. **
  4. **    Editing panel for hotkey configuration
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12. enum    {    GAD_TERMTOFRONT=1,GAD_BUFFERTOFRONT,GAD_SKIPDIAL,GAD_ABORTAREXX,
  13.         GAD_PRIORITY,GAD_HOTKEYS,GAD_USE,GAD_LOAD,GAD_SAVE,GAD_CANCEL
  14.     };
  15.  
  16. struct Library *KeymapBase;
  17.  
  18.     // All the rawkey codes we know about
  19.  
  20. #define RAWKEY_CURSOR_UP    76
  21. #define RAWKEY_CURSOR_DOWN    77
  22. #define RAWKEY_CURSOR_RIGHT    78
  23. #define RAWKEY_CURSOR_LEFT    79
  24.  
  25. #define RAWKEY_F1        80
  26. #define RAWKEY_F2        81
  27. #define RAWKEY_F3        82
  28. #define RAWKEY_F4        83
  29. #define RAWKEY_F5        84
  30. #define RAWKEY_F6        85
  31. #define RAWKEY_F7        86
  32. #define RAWKEY_F8        87
  33. #define RAWKEY_F9        88
  34. #define RAWKEY_F10        89
  35.  
  36. #define RAWKEY_HELP        95
  37.  
  38. STATIC BOOLEAN __regargs
  39. GoodCode(STRPTR Code)
  40. {
  41.     IX Expression;
  42.  
  43.     return((BOOLEAN)(ParseIX(Code,&Expression) == 0));
  44. }
  45.  
  46.     /* EditRoutine():
  47.      *
  48.      *    A special string gadget editing routine for key
  49.      *    combination input.
  50.      */
  51.  
  52. ULONG __saveds __asm
  53. EditRoutine(register __a0 struct Hook *Hook,register __a2 struct SGWork *Work,register __a1 ULONG *Msg)
  54. {
  55.     struct InputEvent    Event;
  56.     ULONG            Qualifier;
  57.     UWORD            Code;
  58.     UBYTE            Key[10];
  59.     WORD            KeyLen;
  60.     STRPTR            KeyName;
  61.  
  62.         // If the gadget just got activated or the caps lock key
  63.         // is active, don't change anything
  64.  
  65.     if(*Msg == SGH_CLICK || (*Msg == SGH_KEY && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CAPSLOCK)))
  66.         return(TRUE);
  67.     else
  68.     {
  69.             // Complain if this is not what we expect to be fun
  70.  
  71.         if(*Msg != SGH_KEY)
  72.             return(FALSE);
  73.     }
  74.  
  75.         // Ditch the qualifier keys
  76.  
  77.     if(Work -> IEvent -> ie_Code >= 96 && Work -> IEvent -> ie_Code <= 103)
  78.     {
  79.         Work -> Actions    &= ~(SGA_USE | SGA_BEEP);
  80.  
  81.         return(TRUE);
  82.     }
  83.  
  84.         // Strip all the qualifiers we don't want
  85.  
  86.     Qualifier = Work -> IEvent -> ie_Qualifier & ~(IEQUALIFIER_REPEAT | IEQUALIFIER_INTERRUPT | IEQUALIFIER_MULTIBROADCAST | IEQUALIFIER_RELATIVEMOUSE);
  87.  
  88.         // Check for raw keys
  89.  
  90.     switch(Work -> IEvent -> ie_Code)
  91.     {
  92.         case RAWKEY_CURSOR_UP:
  93.         case RAWKEY_CURSOR_DOWN:
  94.         case RAWKEY_CURSOR_RIGHT:
  95.         case RAWKEY_CURSOR_LEFT:
  96.  
  97.                 // A cursor key was pressed, check if there
  98.                 // is probably some special feature involved
  99.  
  100.             if(!(Qualifier & ~(IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
  101.                 return(TRUE);
  102.  
  103.             // FALLS THROUGH TO:
  104.  
  105.         case RAWKEY_F1:
  106.         case RAWKEY_F2:
  107.         case RAWKEY_F3:
  108.         case RAWKEY_F4:
  109.         case RAWKEY_F5:
  110.         case RAWKEY_F6:
  111.         case RAWKEY_F7:
  112.         case RAWKEY_F8:
  113.         case RAWKEY_F9:
  114.         case RAWKEY_F10:
  115.  
  116.         case RAWKEY_HELP:
  117.  
  118.                 // Ok, so this is a raw key event
  119.  
  120.             Code    = Work -> IEvent -> ie_Code;
  121.             KeyLen    = 0;
  122.  
  123.             break;
  124.  
  125.         default:
  126.  
  127.                 // Make a copy of the inputevent and
  128.                 // clear the qualifier bits
  129.  
  130.             CopyMem(Work -> IEvent,&Event,sizeof(struct InputEvent));
  131.  
  132.             Event . ie_Qualifier = NULL;
  133.  
  134.             Code = 0;
  135.  
  136.                 // Translate the event
  137.  
  138.             if((KeyLen = MapRawKey(&Event,Key,10,NULL)) < 0)
  139.                 KeyLen = 10;
  140.  
  141.             break;
  142.     }
  143.  
  144.         // Is the user holding down a single Amiga key?
  145.  
  146.     if(KeyLen && (Qualifier & IEQUALIFIER_RCOMMAND) && !(Qualifier & ~IEQUALIFIER_RCOMMAND))
  147.     {
  148.         UBYTE Char = ToUpper(Key[0]);
  149.  
  150.             // Undo and clear are supported
  151.  
  152.         if(Char == 'Q' || Char == 'X')
  153.             return(TRUE);
  154.     }
  155.  
  156.         // Can we safely continue?
  157.  
  158.     if((!Code && !KeyLen) || KeyLen > 1 || (!Code && KeyLen && !Key[0]))
  159.     {
  160.         Work -> Actions    = (Work -> Actions & ~SGA_USE) | SGA_BEEP;
  161.  
  162.         return(TRUE);
  163.     }
  164.  
  165.         // Take care of special characters
  166.  
  167.     if(KeyLen)
  168.     {
  169.         STATIC struct { UBYTE Code; STRPTR Name; } KeyTable[] =
  170.         {
  171.             '\r',    "Return",
  172.             '\b',    "Backspace",
  173.             '\033',    "Escape",
  174.             ' ',    "Spacebar",
  175.             ',',    "Comma",
  176.             '\177',    "Delete",
  177.             '\t',    "Tab",
  178.  
  179.             0
  180.         };
  181.  
  182.         BOOL GotIt = FALSE;
  183.         WORD i;
  184.  
  185.             // Carriage return was pressed
  186.  
  187.         if(Key[0] == '\r')
  188.         {
  189.                 // This probably ends input
  190.  
  191.             if(!Qualifier)
  192.             {
  193.                 Work -> Actions    = (Work -> Actions & ~SGA_BEEP) | SGA_USE | SGA_END;
  194.  
  195.                 return(TRUE);
  196.             }
  197.             else
  198.             {
  199.                     // Is this the enter key?
  200.  
  201.                 if(Qualifier & IEQUALIFIER_NUMERICPAD)
  202.                 {
  203.                     KeyName = "Enter";
  204.  
  205.                     Qualifier &= ~IEQUALIFIER_NUMERICPAD;
  206.  
  207.                     GotIt = TRUE;
  208.                 }
  209.             }
  210.         }
  211.  
  212.             // If this is just the tab key, pass it through cleanly
  213.  
  214.         if(Key[0] == '\t' && !(Qualifier & ~(IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
  215.             return(TRUE);
  216.  
  217.             // Now check for special characters
  218.  
  219.         Key[0] = ToUpper(Key[0]);
  220.  
  221.         if(!GotIt)
  222.         {
  223.             for(i = 0 ; KeyTable[i] . Code ; i++)
  224.             {
  225.                 if(KeyTable[i] . Code == Key[0])
  226.                 {
  227.                     KeyName = KeyTable[i] . Name;
  228.  
  229.                     GotIt = TRUE;
  230.  
  231.                     break;
  232.                 }
  233.             }
  234.         }
  235.  
  236.             // If no special character is involved,
  237.             // use the vanilla character code
  238.  
  239.         if(!GotIt)
  240.         {
  241.             if((Key[0] > ' ' && Key[0] < 127) || Key[0] >= 160)
  242.             {
  243.                 Key[1] = 0;
  244.  
  245.                 KeyName = Key;
  246.             }
  247.             else
  248.             {
  249.                 Work -> Actions    = (Work -> Actions & ~SGA_USE) | SGA_BEEP;
  250.  
  251.                 return(TRUE);
  252.             }
  253.         }
  254.     }
  255.     else
  256.     {
  257.             // Special raw key code table
  258.  
  259.         STATIC struct { UWORD Code; STRPTR Name; } RawTable[] =
  260.         {
  261.             RAWKEY_CURSOR_UP,    "Cursor_Up",
  262.             RAWKEY_CURSOR_DOWN,    "Cursor_Down",
  263.             RAWKEY_CURSOR_RIGHT,    "Cursor_Right",
  264.             RAWKEY_CURSOR_LEFT,    "Cursor_Left",
  265.  
  266.             RAWKEY_F1,        "F1",
  267.             RAWKEY_F2,        "F2",
  268.             RAWKEY_F3,        "F3",
  269.             RAWKEY_F4,        "F4",
  270.             RAWKEY_F5,        "F5",
  271.             RAWKEY_F6,        "F6",
  272.             RAWKEY_F7,        "F7",
  273.             RAWKEY_F8,        "F8",
  274.             RAWKEY_F9,        "F9",
  275.             RAWKEY_F10,        "F10",
  276.  
  277.             RAWKEY_HELP,        "Help",
  278.  
  279.             0
  280.         };
  281.  
  282.         WORD i;
  283.  
  284.             // One eventually must match
  285.  
  286.         for(i = 0 ; RawTable[i] . Code ; i++)
  287.         {
  288.             if(Code == RawTable[i] . Code)
  289.             {
  290.                 KeyName = RawTable[i] . Name;
  291.  
  292.                 break;
  293.             }
  294.         }
  295.     }
  296.  
  297.         // Take care of the qualifiers. Note that we do not distinguish
  298.         // between the left and right shift/alt keys
  299.  
  300.     if(Qualifier)
  301.     {
  302.         STATIC struct { ULONG Qualifier; STRPTR Name; } QualifierTable[] =
  303.         {
  304.             IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT,    "Shift ",
  305.             IEQUALIFIER_LALT | IEQUALIFIER_RALT,        "Alt ",
  306.             IEQUALIFIER_LCOMMAND,                "LAmiga ",
  307.             IEQUALIFIER_RCOMMAND,                "RAmiga ",
  308.             IEQUALIFIER_LEFTBUTTON,                "Left_Button ",
  309.             IEQUALIFIER_MIDBUTTON,                "Middle_Button ",
  310.             IEQUALIFIER_RBUTTON,                "Right_Button ",
  311.             IEQUALIFIER_NUMERICPAD,                "Numeric_Pad ",
  312.  
  313.             0
  314.         };
  315.  
  316.         WORD i;
  317.  
  318.             // Ok, now start building the string
  319.  
  320.         Work -> WorkBuffer[0] = 0;
  321.  
  322.         for(i = 0 ; QualifierTable[i] . Qualifier ; i++)
  323.         {
  324.             if(Qualifier & QualifierTable[i] . Qualifier)
  325.                 strcat(Work -> WorkBuffer,QualifierTable[i] . Name);
  326.         }
  327.  
  328.             // Add the key itself
  329.  
  330.         strcat(Work -> WorkBuffer,KeyName);
  331.  
  332.             // Update the work data
  333.  
  334.         Work -> NumChars    = strlen(Work -> WorkBuffer);
  335.         Work -> BufferPos    = Work -> NumChars;
  336.  
  337.             // Finished...
  338.  
  339.         Work -> Actions    = (Work -> Actions & ~(SGA_BEEP | SGA_PREVACTIVE | SGA_NEXTACTIVE | SGA_END)) | SGA_REDISPLAY | SGA_USE;
  340.     }
  341.     else
  342.         Work -> Actions    &= ~(SGA_USE | SGA_BEEP);
  343.  
  344.     return(TRUE);
  345. }
  346.  
  347. BYTE __regargs
  348. HotkeyPanel(struct Hotkeys *Hotkeys)
  349. {
  350.     STATIC struct Hook EditHook = { {NULL}, (HOOKFUNC)EditRoutine };
  351.  
  352.     struct LayoutHandle    *Handle;
  353.     struct Hotkeys         PrivateHotkeys;
  354.     ULONG             OldCRC;
  355.  
  356.     KeymapBase = OpenLibrary("keymap.library",0);
  357.  
  358.     OldCRC = DoCRC(Hotkeys,sizeof(struct Hotkeys));
  359.  
  360.     CopyMem(Hotkeys,&PrivateHotkeys,sizeof(struct Hotkeys));
  361.  
  362.     if(Handle = LT_CreateHandleTags(Window -> WScreen,
  363.         LH_LocaleHook,    &LocaleHook,
  364.         LH_ExitFlush,    FALSE,
  365.     TAG_DONE))
  366.     {
  367.         struct Window *PanelWindow;
  368.  
  369.         LT_New(Handle,
  370.             LA_Type,    VERTICAL_KIND,
  371.         TAG_DONE);
  372.         {
  373.             LT_New(Handle,
  374.                 LA_Type,    VERTICAL_KIND,
  375.                 LA_LabelID,    MSG_V36_0083,
  376.             TAG_DONE);
  377.             {
  378.                 LT_New(Handle,
  379.                     LA_Type,    STRING_KIND,
  380.                     LA_LabelID,    MSG_HOTKEYPANEL_TERM_SCREEN_TO_FRONT_GAD,
  381.                     LA_STRPTR,    Hotkeys -> termScreenToFront,
  382.                     LA_Chars,    30,
  383.                     GTST_MaxChars,    255,
  384.                     LA_ID,        GAD_TERMTOFRONT,
  385.  
  386.                     KeymapBase ? GTST_EditHook : TAG_IGNORE,&EditHook,
  387.                 TAG_DONE);
  388.  
  389.                 LT_New(Handle,
  390.                     LA_Type,    STRING_KIND,
  391.                     LA_LabelID,    MSG_HOTKEYPANEL_BUFFER_SCREEN_TO_FRONT_GAD,
  392.                     LA_STRPTR,    Hotkeys -> BufferScreenToFront,
  393.                     GTST_MaxChars,    255,
  394.                     LA_ID,        GAD_BUFFERTOFRONT,
  395.  
  396.                     KeymapBase ? GTST_EditHook : TAG_IGNORE,&EditHook,
  397.                 TAG_DONE);
  398.  
  399.                 LT_New(Handle,
  400.                     LA_Type,    STRING_KIND,
  401.                     LA_LabelID,    MSG_HOTKEYPANEL_SKIP_DIAL_ENTRY_GAD,
  402.                     LA_STRPTR,    Hotkeys -> SkipDialEntry,
  403.                     GTST_MaxChars,    255,
  404.                     LA_ID,        GAD_SKIPDIAL,
  405.  
  406.                     KeymapBase ? GTST_EditHook : TAG_IGNORE,&EditHook,
  407.                 TAG_DONE);
  408.  
  409.                 LT_New(Handle,
  410.                     LA_Type,    STRING_KIND,
  411.                     LA_LabelID,    MSG_HOTKEYPANEL_ABORT_AREXX_GAD,
  412.                     LA_STRPTR,    Hotkeys -> AbortARexx,
  413.                     GTST_MaxChars,    255,
  414.                     LA_ID,        GAD_ABORTAREXX,
  415.  
  416.                     KeymapBase ? GTST_EditHook : TAG_IGNORE,&EditHook,
  417.                 TAG_DONE);
  418.  
  419.                 LT_EndGroup(Handle);
  420.             }
  421.  
  422.             LT_New(Handle,
  423.                 LA_Type,        VERTICAL_KIND,
  424.                 LA_LabelID,        MSG_V36_0084,
  425.             TAG_DONE);
  426.             {
  427.                 LT_New(Handle,
  428.                     LA_Type,        SliderType,
  429.                     LA_LabelID,        MSG_HOTKEYPANEL_COMMODITY_PRIORITY_GAD,
  430.                     LA_BYTE,        &Hotkeys -> CommodityPriority,
  431.                     GTSL_Min,        -128,
  432.                     GTSL_Max,        127,
  433.                     GTSL_LevelFormat,    "%4ld",
  434.                     LA_Chars,        16,
  435.                     LA_ID,            GAD_PRIORITY,
  436.                 TAG_DONE);
  437.  
  438.                 LT_New(Handle,
  439.                     LA_Type,    CHECKBOX_KIND,
  440.                     LA_LabelID,    MSG_HOTKEYPANEL_HOTKEYS_ENABLED_GAD,
  441.                     LA_BYTE,    &Hotkeys -> HotkeysEnabled,
  442.                     LA_ID,        GAD_HOTKEYS,
  443.                 TAG_DONE);
  444.  
  445.                 LT_EndGroup(Handle);
  446.             }
  447.  
  448.             LT_New(Handle,
  449.                 LA_Type,VERTICAL_KIND,
  450.             TAG_DONE);
  451.             {
  452.                 LT_New(Handle,
  453.                     LA_Type,    XBAR_KIND,
  454.                     LAXB_FullSize,    TRUE,
  455.                 TAG_DONE);
  456.  
  457.                 LT_EndGroup(Handle);
  458.             }
  459.  
  460.             LT_New(Handle,LA_Type,HORIZONTAL_KIND,
  461.                 LAGR_SameSize,    TRUE,
  462.                 LAGR_Spread,    TRUE,
  463.             TAG_DONE);
  464.             {
  465.                 LT_New(Handle,
  466.                     LA_Type,    BUTTON_KIND,
  467.                     LA_LabelID,    MSG_GLOBAL_USE_GAD,
  468.                     LA_ID,        GAD_USE,
  469.                     LABT_ReturnKey,    TRUE,
  470.                     LABT_ExtraFat,    TRUE,
  471.                 TAG_DONE);
  472.  
  473.                 LT_New(Handle,
  474.                     LA_Type,    BUTTON_KIND,
  475.                     LA_LabelID,    MSG_GLOBAL_LOAD_GAD,
  476.                     LA_ID,        GAD_LOAD,
  477.                     LABT_ExtraFat,    TRUE,
  478.                 TAG_DONE);
  479.  
  480.                 LT_New(Handle,
  481.                     LA_Type,    BUTTON_KIND,
  482.                     LA_LabelID,    MSG_GLOBAL_SAVE_GAD,
  483.                     LA_ID,        GAD_SAVE,
  484.                     LABT_ExtraFat,    TRUE,
  485.                 TAG_DONE);
  486.  
  487.                 LT_New(Handle,
  488.                     LA_Type,    BUTTON_KIND,
  489.                     LA_LabelID,    MSG_GLOBAL_CANCEL_GAD,
  490.                     LA_ID,        GAD_CANCEL,
  491.                     LABT_EscKey,    TRUE,
  492.                     LABT_ExtraFat,    TRUE,
  493.                 TAG_DONE);
  494.  
  495.                 LT_EndGroup(Handle);
  496.             }
  497.  
  498.             LT_EndGroup(Handle);
  499.         }
  500.  
  501.         if(PanelWindow = LT_Layout(Handle,LocaleString(MSG_HOTKEYPANEL_HOTKEY_PREFERENCES_TXT),NULL,0,0,IDCMP_CLOSEWINDOW,0,
  502.             LAWN_HelpHook,        &GuideHook,
  503.             LAWN_Parent,        Window,
  504.             WA_DepthGadget,        TRUE,
  505.             WA_CloseGadget,        TRUE,
  506.             WA_DragBar,        TRUE,
  507.             WA_RMBTrap,        TRUE,
  508.             WA_Activate,        TRUE,
  509.         TAG_DONE))
  510.         {
  511.             struct IntuiMessage    *Message;
  512.             BOOLEAN             Done = FALSE;
  513.             ULONG             MsgClass,
  514.                          MsgQualifier;
  515.             UWORD             MsgCode;
  516.             struct Gadget        *MsgGadget;
  517.  
  518.             struct FileRequester    *FileRequest;
  519.             UBYTE             DummyBuffer[MAX_FILENAME_LENGTH],
  520.                         *DummyChar;
  521.  
  522.             STRPTR             String;
  523.  
  524.             GuideContext(CONTEXT_HOTKEYS);
  525.  
  526.             PushWindow(PanelWindow);
  527.  
  528.             do
  529.             {
  530.                 if(Wait(PORTMASK(PanelWindow -> UserPort) | SIG_BREAK) & SIG_BREAK)
  531.                 {
  532.                     CopyMem(&PrivateHotkeys,Hotkeys,sizeof(struct Hotkeys));
  533.  
  534.                     break;
  535.                 }
  536.  
  537.                 while(Message = (struct IntuiMessage *)GT_GetIMsg(PanelWindow -> UserPort))
  538.                 {
  539.                     MsgClass    = Message -> Class;
  540.                     MsgQualifier    = Message -> Qualifier;
  541.                     MsgCode        = Message -> Code;
  542.                     MsgGadget    = (struct Gadget *)Message -> IAddress;
  543.  
  544.                     GT_ReplyIMsg(Message);
  545.  
  546.                     LT_HandleInput(Handle,MsgQualifier,&MsgClass,&MsgCode,&MsgGadget);
  547.  
  548.                     if(MsgClass == IDCMP_CLOSEWINDOW)
  549.                     {
  550.                         CopyMem(&PrivateHotkeys,Hotkeys,sizeof(struct Hotkeys));
  551.  
  552.                         Done = TRUE;
  553.                     }
  554.  
  555.                     if(MsgClass == IDCMP_GADGETUP)
  556.                     {
  557.                         switch(MsgGadget -> GadgetID)
  558.                         {
  559.                             case GAD_TERMTOFRONT:
  560.                             case GAD_BUFFERTOFRONT:
  561.                             case GAD_SKIPDIAL:
  562.                             case GAD_ABORTAREXX:
  563.  
  564.                                 String = LT_GetString(Handle,MsgGadget -> GadgetID);
  565.  
  566.                                 if(!GoodCode(String))
  567.                                 {
  568.                                     DisplayBeep(PanelWindow -> WScreen);
  569.  
  570.                                     LT_Activate(Handle,MsgGadget -> GadgetID);
  571.                                 }
  572.  
  573.                                 break;
  574.  
  575.                             case GAD_USE:
  576.  
  577.                                 LT_UpdateStrings(Handle);
  578.  
  579.                                 Done = TRUE;
  580.                                 break;
  581.  
  582.                             case GAD_CANCEL:
  583.  
  584.                                 CopyMem(&PrivateHotkeys,Hotkeys,sizeof(struct Hotkeys));
  585.  
  586.                                 Done = TRUE;
  587.                                 break;
  588.  
  589.                             case GAD_LOAD:
  590.  
  591.                                 SplitFileName(LastKeys,&DummyChar,DummyBuffer);
  592.  
  593.                                 LT_LockWindow(PanelWindow);
  594.  
  595.                                 if(FileRequest = GetFile(PanelWindow,LocaleString(MSG_HOTKEYPANEL_LOAD_HOTKEYS_TXT),DummyBuffer,FilePart(LastKeys),DummyBuffer,"#?.prefs",FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_LOAD_TXT),TRUE))
  596.                                 {
  597.                                     if(!LoadHotkeys(DummyBuffer,Hotkeys))
  598.                                         ShowError(PanelWindow,ERR_LOAD_ERROR,IoErr(),DummyBuffer);
  599.                                     else
  600.                                     {
  601.                                         strcpy(LastKeys,DummyBuffer);
  602.  
  603.                                         LT_SetAttributes(Handle,GAD_TERMTOFRONT,
  604.                                             GTST_String,Hotkeys -> termScreenToFront,
  605.                                         TAG_DONE);
  606.  
  607.                                         LT_SetAttributes(Handle,GAD_BUFFERTOFRONT,
  608.                                             GTST_String,Hotkeys -> BufferScreenToFront,
  609.                                         TAG_DONE);
  610.  
  611.                                         LT_SetAttributes(Handle,GAD_SKIPDIAL,
  612.                                             GTST_String,Hotkeys -> SkipDialEntry,
  613.                                         TAG_DONE);
  614.  
  615.                                         LT_SetAttributes(Handle,GAD_ABORTAREXX,
  616.                                             GTST_String,Hotkeys -> AbortARexx,
  617.                                         TAG_DONE);
  618.  
  619.                                         LT_SetAttributes(Handle,GAD_PRIORITY,
  620.                                             GTSL_Level,Hotkeys -> CommodityPriority,
  621.                                         TAG_DONE);
  622.  
  623.                                         LT_SetAttributes(Handle,GAD_HOTKEYS,
  624.                                             GTCB_Checked,Hotkeys -> HotkeysEnabled,
  625.                                         TAG_DONE);
  626.  
  627.                                         OldCRC = DoCRC(Hotkeys,sizeof(struct Hotkeys));
  628.  
  629.                                         HotkeysChanged = FALSE;
  630.                                     }
  631.  
  632.                                     FreeAslRequest(FileRequest);
  633.                                 }
  634.  
  635.                                 LT_UnlockWindow(PanelWindow);
  636.  
  637.                                 break;
  638.  
  639.                             case GAD_SAVE:
  640.  
  641.                                 LT_UpdateStrings(Handle);
  642.  
  643.                                 SplitFileName(LastKeys,&DummyChar,DummyBuffer);
  644.  
  645.                                 LT_LockWindow(PanelWindow);
  646.  
  647.                                 if(FileRequest = GetFile(PanelWindow,LocaleString(MSG_HOTKEYPANEL_SAVE_HOTKEYS_TXT),DummyBuffer,FilePart(LastKeys),DummyBuffer,"#?.prefs",TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),TRUE))
  648.                                 {
  649.                                     if(!WriteIFFData(DummyBuffer,Hotkeys,sizeof(struct Hotkeys),ID_HOTK))
  650.                                         ShowError(PanelWindow,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  651.                                     else
  652.                                     {
  653.                                         strcpy(LastKeys,DummyBuffer);
  654.  
  655.                                         OldCRC = DoCRC(Hotkeys,sizeof(struct Hotkeys));
  656.  
  657.                                         HotkeysChanged = FALSE;
  658.                                     }
  659.  
  660.                                     FreeAslRequest(FileRequest);
  661.                                 }
  662.  
  663.                                 LT_UnlockWindow(PanelWindow);
  664.  
  665.                                 break;
  666.                         }
  667.                     }
  668.                 }
  669.             }
  670.             while(!Done);
  671.  
  672.             PopWindow();
  673.         }
  674.  
  675.         LT_DeleteHandle(Handle);
  676.     }
  677.  
  678.     CloseLibrary(KeymapBase);
  679.  
  680.     HotkeysChanged |= (OldCRC != DoCRC(Hotkeys,sizeof(struct Hotkeys)));
  681.  
  682.     return((BYTE)memcmp(&PrivateHotkeys,Hotkeys,sizeof(struct Hotkeys)));
  683. }
  684.